package com.atguigu.gmall.item.service.impl;

import com.alibaba.fastjson.JSON;
import com.atguigu.gmall.item.config.ThreadPoolConfig;
import com.atguigu.gmall.item.service.ItemApiService;
import com.atguigu.gmall.list.client.ListFeignClient;
import com.atguigu.gmall.model.product.BaseCategoryView;
import com.atguigu.gmall.model.product.SkuInfo;
import com.atguigu.gmall.model.product.SpuSaleAttr;
import com.atguigu.gmall.product.client.ProductFeignClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @author Administrator
 * @create 2020-05-15 19:48
 */
@Service
public class ItemApiServiceImpl implements ItemApiService {

    @Autowired
    private ProductFeignClient productFeignClient;
    @Autowired
    private ThreadPoolExecutor threadPoolExecutor;//自定义的线程池
    @Autowired
    private ListFeignClient listFeignClient;


    @Override
    public Map<String, Object> getItem(Long skuId) {
        Map<String, Object> result = new HashMap<>();

        //开启线程: 线程1和3几乎同时执行，2.4.5依托于1的结果，等1线程执行完成后执行
        /*
        多线程远程调用微服务，优化迸发。
         */
//        1、根据SkuID查询SkuInfo信息
        //SkuInfo skuInfo = productFeignClient.getSkuInfo(skuId);
       // result.put("skuInfo",skuInfo);
        CompletableFuture<SkuInfo> skuInfoCompletableFuture=CompletableFuture.supplyAsync(()->{
            SkuInfo skuInfo = productFeignClient.getSkuInfo(skuId);
            result.put("skuInfo", skuInfo);
            return skuInfo;
        },threadPoolExecutor);
//        2、根据三级分类ID查询一二三级分类
        CompletableFuture<Void> categoryView1 = skuInfoCompletableFuture.thenAcceptAsync((skuInfo) -> {
            BaseCategoryView categoryView = productFeignClient.getCategoryView(skuInfo.getCategory3Id());
            result.put("categoryView", categoryView);
        }, threadPoolExecutor);
//        3、根据skuId查询库存表中的价格
        CompletableFuture<Void> priceCompletableFuture=CompletableFuture.runAsync(()->{
            BigDecimal skuPrice = productFeignClient.getSkuPrice(skuId);
            result.put("price",skuPrice);
        },threadPoolExecutor);

//        4、根据spuId查询销售属性及属性值 集合
//        根据skuId查询当前选中项
        CompletableFuture<Void> spuSaleAttrList = skuInfoCompletableFuture.thenAcceptAsync((skuInfo) -> {
            List<SpuSaleAttr> spuSaleAttrListCheckBySku = productFeignClient
                    .getSpuSaleAttrListCheckBySku(skuInfo.getId(), skuInfo.getSpuId());
            result.put("spuSaleAttrList", spuSaleAttrListCheckBySku);
        }, threadPoolExecutor);
//        5、根据spuId查询销售组合与SkuId之间的对应
        CompletableFuture<Void> valuesSkuJson = skuInfoCompletableFuture.thenAcceptAsync((skuInfo) -> {
            Map skuValueIdsMap = productFeignClient.getSkuValueIdsMap(skuInfo.getSpuId());
            result.put("valuesSkuJson", JSON.toJSONString(skuValueIdsMap));
        }, threadPoolExecutor);

        //选择要等待上面的哪些线程执行完成后返回结果  也可以选择不等
        //本次是必须要等待上面多线程全部执行完成
        CompletableFuture.allOf(skuInfoCompletableFuture,
                categoryView1,priceCompletableFuture,spuSaleAttrList,valuesSkuJson).join();

        //6.访问详情页面时加热度 listFeignClient
        CompletableFuture.runAsync(()->{
            listFeignClient.incrHotScore(skuId);
        },threadPoolExecutor);
        return result;
    }

}
